package com.citcc.api.netty.xc.xcserver;

import com.citcc.api.netty.EchargeConstants;
import com.citcc.api.netty.bean.ConsuMessage;
import com.citcc.api.netty.server.ChannelMap;
import com.citcc.api.netty.utils.HexUtil;
import com.citcc.api.netty.utils.XcUtil;
import com.citcc.business.bean.CdzGun;
import com.citcc.business.bean.CdzIndent;
import com.citcc.business.bean.UserOrderEntity;
import com.citcc.business.bean.UserOrderEntityExample;
import com.citcc.business.service.CdzGunService;
import com.citcc.business.service.CdzIndentService;
import com.citcc.business.service.CdzStakeService;
import com.citcc.business.service.ScanCodeService;
import com.citcc.business.util.CollectionUtil;
import com.citcc.framework.sms.JsonResult;
import com.github.pagehelper.util.StringUtil;

import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import javax.annotation.Generated;

import org.apache.commons.lang3.time.FastDateFormat;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @author liyachong
 * @date 2019/5/28
 * @time 14:41
 */
@SuppressWarnings("all")
//@Component
public class XcServerToClient {

	private Logger log = LoggerFactory.getLogger(XcServerToClient.class);
	private static List<String> list = Arrays.asList("0","1","2","3");
	
	static FastDateFormat format = FastDateFormat.getInstance("yyyyMMddHHmmss");
	// 扩展
	public static ScanCodeService scanCodeService;
	
	//订单业务
    public static CdzIndentService cdzIndentService;

	/**
	 * 下发启动充电指令
	 * 
	 * @param msg
	 * @param
	 * @return 1 开启充电成功 ，2 充电桩不在线
	 */
	public int startCmd(ConsuMessage msg) {
		String terminalNo = msg.getTerminalNo();
		String source = msg.getSource()+"";
		String phone = msg.getPhone();
		long time = msg.getTime();
		long money = msg.getMoney();
		long dl = msg.getDl();
		String mode = msg.getMode();
		String id = msg.getId();
		if(StringUtils.isEmpty(id)){
        	log.warn("不存在订单------------------");
        	return 10;
        }
		log.info("终端号=="+terminalNo+"-->枪号="+source+"-->手机号:"+phone+"-->充电时间:"+time+"-->充电模式:"+mode+"-->充电金额:"+money+"-->充电电量:"+dl+"-->订单id:"+id+"-->序号:"+msg.getNo());
        if(!list.contains(mode)){
        	log.warn("xc充电模式不合法------------------");
        	return 10;
        }
        if("1".equals(mode) && StringUtils.isEmpty(money)){
        	log.warn("xc充电模式为1时，充电金额不能为空------------------");
        	return 10;
        }
        if("2".equals(mode) && StringUtils.isEmpty(time)){
        	log.warn("xc充电模式为2时，充电时间不能为空------------------");
        	return 10;
        }
        if("3".equals(mode) && StringUtils.isEmpty(dl)){
        	log.warn("xc充电模式为3时，充电电量不能为空------------------");
        	return 10;
        }
		Channel channel = ChannelMap.getChannelByName(terminalNo + "");
		if(channel==null){
			log.error("xc监控平台下发开启充电指令失败=========设备不在线==" + msg.getDeviceNo());
			return 6;
		}
		boolean res = channel.isConnected();
		log.warn("xc监控平台下发开启充电指令=========设备号==" + terminalNo+"----状态:"+res);
		if (channel.isConnected()) {
			if (StringUtil.isEmpty(terminalNo) || StringUtil.isEmpty(source)) {
				log.error("xc下发开启充电指令时终端号:" + terminalNo + "-->枪号:" + source + "-->都不能为空");
				return 3;
			}
			
			log.info("xc下发开启指令时---终端号:"+terminalNo+"-->枪号:"+source);
			// 判断该终端号+枪号 是否可用
			CdzGun cdzGun = scanCodeService.checkCdzGun(source + "", terminalNo);
			//链接成功   枪已连接
			if (cdzGun != null && "1".equals(cdzGun.getStatus())) {//未充电
				UserOrderEntity e = scanCodeService.getCdOrder(id);
				if(e==null || !("0".equals(e.getDelFlag())) || !("1".equals(e.getChargeState()))){
					log.error("xc下发开启充电指令时终端号:" + terminalNo + "-->枪号:" + source + "-->手机号"+msg.getPhone()+"-->没有查询到未充电的有效订单");
					return 5;
				}
				log.info("xc接收下发开启指令时---终端号:"+terminalNo+"-->枪号:"+source+"-->流水号:"+e.getTradeNo()+"-->手机号:"+phone);
				BigDecimal dj = e.getPayNumber();
				if(dj==null){
					dj = BigDecimal.ZERO;
				}
				dj = dj.setScale(0, BigDecimal.ROUND_HALF_UP);
				long m = dj.longValue();
				ChannelBuffer body = ChannelBuffers.buffer(48);
				body.writeShort(0x002E);//帧长度
				body.writeShort(0xFFD1);//帧长度取反
				body.writeByte(msg.getNo());//TODO 序号 0x00
				//数据对象  枪号
				if ("0".equals(source)) {
					body.writeByte(0x00);//枪号
				} else if ("1".equals(source)) {
					body.writeByte(0x01);//枪号
				} else if ("2".equals(source)) {
					body.writeByte(0x02);//枪号
				} else if ("3".equals(source)) {
					body.writeByte(0x03);//枪号
				} else if ("4".equals(source)) {
					body.writeByte(0x04);//枪号
				}
				body.writeByte(0x44);//开启充电指令
				// TODO  替换
				
				body.writeBytes(HexUtil.hexStringToByte(XcUtil.convertStringToHex(e.getTradeNo())));//补全22位作为流水号
				body.writeBytes(HexUtil.hexStringToByte(XcUtil.convertStringToHex("00000"+phone)));//补全16位作为卡号    00000+phone   
				//body.writeBytes(HexUtil.hexStringToByte("32303139303433303039343534373630383533323635"));//补全22位作为流水号
				//body.writeBytes(HexUtil.hexStringToByte(XcUtil.convertStringToHex("0000013606086270")));//补全16位作为卡号    00000+phone
				// 充电模式和充电参数
				if("0".equals(msg.getMode())){//自动充电
					body.writeByte(0x00);
					body.writeShort(0x0000);
				}else if("1".equals(msg.getMode())){//金额模式  单位元
					body.writeByte(0x01);
					String je = Long.toHexString(money);
					String realJe = HexUtil.befor0(je, 4);
					body.writeBytes(HexUtil.hexStringToByte(realJe));//单位元  000D 
					//body.writeBytes(HexUtil.hexStringToByte("000D"));
				}else if("3".equals(msg.getMode())){//时间模式  单位分
					String h = Long.toHexString(time);
					String ss = HexUtil.befor0(h, 4);
					body.writeByte(0x03);
					body.writeBytes(HexUtil.hexStringToByte(ss));
				}else if("2".equals(msg.getMode())){//电量模式
					String h = Long.toHexString(dl);
					String ss = HexUtil.befor0(h, 4);
					body.writeByte(0x02);
					body.writeBytes(HexUtil.hexStringToByte(ss));
				}
				msg.setMsgBody(body);
				channel.write(msg);
				log.error("xc监控平台下发开启充电指令成功=========设备号==" + terminalNo);
				return 200;
			} else {
				log.error("xc下发开启充电指令时终端号:" + terminalNo + "-->枪号:" + source + "-->该枪不在空闲转态或不存在该枪的信息");
				return 4;
			}
		} else {
			log.error("监控平台下发开启充电指令失败=========设备不在线==" + msg.getDeviceNo());
			return 2;// 不在线
		}
	}

	/**
	 * 下发启动停止指令
	 * 
	 * @param msg
	 * @param
	 * @return 1 成功 ，2 充电桩不在线
	 */
	public int stopCmd(ConsuMessage msg) {
		String terminalNo = msg.getTerminalNo();
		String qh = msg.getSource()+"";
		Channel c = ChannelMap.getChannelByName(terminalNo);
		if(c==null){
			log.info("xc监控平台下发停止充电指令失败=========设备不在线==" + terminalNo);
			return 6;
		}
		Channel channel = (Channel) ChannelMap.getChannelByName(terminalNo);
		if (channel.isConnected()) {
			if (StringUtils.isEmpty(terminalNo) || StringUtils.isEmpty(qh)) {
				log.error("xc下发停止充电指令时终端号:" + terminalNo + "-->枪号:" + qh + "-->都不能为空");
				return 3;
			}
			log.info("xc下发关闭指令时---终端号:"+terminalNo+"-->枪号:"+qh);
			CdzGun cdzGun = scanCodeService.checkCdzGun(qh + "", terminalNo);
			//链接成功 充电中状态
			if (cdzGun != null && EchargeConstants.CHARGING_STATUS.equals(cdzGun.getStatus())) {
				ChannelBuffer body = ChannelBuffers.buffer(8);
				body.writeShort(0x0006);//帧长度
				body.writeShort(0xFFF9);//帧长度取反
				body.writeByte(msg.getNo());//序号 0x00
				//数据对象  枪号
				if ("0".equals(qh)) {
					body.writeByte(0x00);//枪号
				} else if ("1".equals(qh)) {
					body.writeByte(0x01);//枪号
				} else if ("2".equals(qh)) {
					body.writeByte(0x02);//枪号
				} else if ("3".equals(qh)) {
					body.writeByte(0x03);//枪号
				} else if ("4".equals(qh)) {
					body.writeByte(0x04);//枪号
				}
				body.writeByte(0x46);//关闭充电指令
				body.writeByte(0x01);//停止充电
				msg.setMsgBody(body);
				channel.write(msg);
				log.info("xc监控平台下发停止充电指令成功=========设备号==" + terminalNo+"-->枪号:"+qh);
				return 200;
			} else {
				log.error("xc下发停止充电指令时终端号:" + terminalNo + "-->枪号:" + qh + "-->该枪不在充电中转态或不存在该枪的信息");
				return 4;
			}
		} else {
			log.info("xc监控平台下发停止充电指令失败=========设备不在线==" + msg.getDeviceNo());
			return 2;// 不在线
		}
	}
	
	 public Date afterHour(Date curDate,int h){
	    	Calendar ca=Calendar.getInstance();
	    	ca.setTime(curDate);
	    	ca.add(Calendar.HOUR_OF_DAY, h);
	    	return ca.getTime();
	    }
	 
	 
	   /**
	     * 生成22位订单编号
	     *
	     * @return
	     */
	    public static String generateOrder() {
	        String order = "";
	        try {
	            order = format.format(new Date()) + (int) ((Math.random() * 9 + 1) * 10000000);
	        } catch (Exception e) {
	            e.printStackTrace();
	            order = "" + (int) ((Math.random() * 9 + 1) * 10000000) + (int) ((Math.random() * 9 + 1) * 10000000) + (int) ((Math.random() * 9 + 1) * 100000);
	        }
	        return order;
	    }

	public static void main(String[] args) {
		String s = generateOrder();
		System.out.println(s);
	}

}
